\chapter{TOUGH2 grids}
\label{t2grids}
\index{TOUGH2 grids}

\section{Introduction}
The \texttt{t2grids} library in PyTOUGH contains classes and routines for manipulating TOUGH2 grids.  It can be imported using the command:

\begin{lstlisting}
    from t2grids import *
\end{lstlisting}

\section{\texttt{t2grid} objects}
\index{PyTOUGH!classes!\texttt{t2grid}}
\index{TOUGH2 grids!objects}

The \texttt{t2grids} library defines a \texttt{t2grid} class, used for representing TOUGH2 grids.  This gives access via Python to the grid's rock types, blocks, connections and other parameters.

Normally a TOUGH2 grid is not created directly, but is either read from a TOUGH2 data file, or constructed from a \hyperref[mulgrids]{\texttt{mulgrid}} geometry object (see chapter \ref{mulgrids}) using the \hyperref[sec:t2grid:fromgeo]{\texttt{fromgeo()}} method.

Printing a \texttt{t2grid} object (e.g. \texttt{print grid}) displays a summary of information about the grid: how many rock types, blocks and connections it contains.

\subsection{Properties}

The main properties of a \texttt{t2grid} object are listed in Table \ref{tb:t2grid_properties}.  Essentially a \texttt{t2grid} object contains collections of blocks, rock types and connections, each accessible either by name or by index.  For example, block `AB 20' in a \texttt{t2grid} called \texttt{grid} is given by \texttt{grid.block['AB 20']}.

Connections are slightly different from blocks or rock types, in that they are not named individually.  However, they can be accessed by the names of the blocks connected by the connection.  For example, the connection between blocks `aa 10' and `ab 10' in a \texttt{t2grid} called \texttt{grid} is given by \texttt{grid.connection['aa 10','ab 10']}.

The \texttt{rocktype\_frequencies} property gives information about how frequently each rock type is used (i.e. how many blocks use that rock type).  It returns a list of tuples, the first element of each tuple being the frequency of use, and the second element being a list of rock type names with that frequency.  The list is given in order of increasing frequency.

The \texttt{rocktype\_indices} property gives an \texttt{np.array} containing the index of the rocktype for each block in the grid.  This can be used to give a plot of rock types, in conjunction with the \texttt{mulgrid} methods \texttt{layer\_plot} or \texttt{slice\_plot}.

\index{TOUGH2 grids!properties}
\begin{table}
  \begin{center}
    \begin{tabular}{|l|l|l|}
      \hline
      \textbf{Property} & \textbf{Type} & \textbf{Description}\\
      \hline
      \texttt{atmosphere\_blocks} & list & atmosphere blocks\\
      \texttt{blocklist} & list & blocks (by index)\\
      \texttt{block} & dictionary & blocks (by name)\\
      \texttt{block\_centres\_defined} & Boolean & whether block centres have been calculated\\
      \texttt{connectionlist} & list & connections (by index)\\
      \texttt{connection} & dictionary & connections (by tuples of block names)\\
      \texttt{num\_atmosphere\_blocks} & integer & number of atmosphere blocks\\
      \texttt{num\_blocks} & integer & number of blocks\\
      \texttt{num\_connections} & integer & number of connections\\
      \texttt{num\_rocktypes} & integer & number of rock types\\
      \texttt{num\_underground\_blocks} & integer & number of non-atmosphere blocks\\
      \texttt{rocktypelist} & list & rock types (by index)\\
      \texttt{rocktype} & dictionary & rock types (by name)\\
      \texttt{rocktype\_frequencies} & list of tuples & frequencies of rock types\\
      \texttt{rocktype\_indices} & \texttt{np.array} & index of rock type for each block\\
      \hline
    \end{tabular}
    \caption{Properties of a \texttt{t2grid} object}
    \label{tb:t2grid_properties}
  \end{center}
\end{table}

\subsection{Methods}
\label{t2gridmethods}

The main methods of a \texttt{t2grid} object are listed in Table \ref{tb:t2grid_methods}.  Details of these methods are given below.

\index{TOUGH2 grids!methods}
\begin{table}
  \begin{center}
    \begin{tabular}{|l|l|p{65mm}|}
      \hline
      \textbf{Method} & \textbf{Type} & \textbf{Description}\\
      \hline
      \hyperref[sec:t2grid:plus]{\texttt{+}} & \hyperref[t2grids]{\texttt{t2grid}} & adds two grids together\\
      \hyperref[sec:t2grid:add_block]{\texttt{add\_block}} & -- & adds a block to the grid\\
      \hyperref[sec:t2grid:add_connection]{\texttt{add\_connection}} & -- & adds a connection to the grid\\
      \hyperref[sec:t2grid:add_rocktype]{\texttt{add\_rocktype}} & -- & adds a rock type to the grid\\
      \hyperref[sec:t2grid:blockmap]{\texttt{blockmap}} & dictionary & returns block name mapping from a geometry\\
      \hyperref[sec:t2grid:block_index]{\texttt{block\_index}} & integer & returns index of a block with a specified name\\
      \hyperref[sec:t2grid:calculate_block_centres]{\texttt{calculate\_block\_centres}} & -- & calculates geometrical centre of all blocks in the grid\\
      \hyperref[sec:t2grid:check]{\texttt{check}} & Boolean & checks grid for errors and optionally fixes them\\
      \hyperref[sec:t2grid:clean_rocktypes]{\texttt{clean\_rocktypes}} & -- & deletes any unused rock types from the grid\\
      \hyperref[sec:t2grid:connection_index]{\texttt{connection\_index}} & integer & returns index of a connection with a specified pair of names\\
      \hyperref[sec:t2grid:copy_connection_directions]{\texttt{copy\_connection\_directions}} & -- & copies connection permeability directions from another grid\\
      \hyperref[sec:t2grid:delete_block]{\texttt{delete\_block}} & -- & deletes a block from the grid\\
      \hyperref[sec:t2grid:delete_connection]{\texttt{delete\_connection}} & -- & deletes a connection from the grid\\
      \hyperref[sec:t2grid:delete_rocktype]{\texttt{delete\_rocktype}} & -- & deletes a rock type from the grid\\
      \hyperref[sec:t2grid:demote_block]{\texttt{demote\_block}} & -- & shifts a block (or blocks) to the end of the blocklist\\
      \hyperref[sec:t2grid:embed]{\texttt{embed}} & \hyperref[t2grids]{\texttt{t2grid}} & embeds a subgrid inside one block of another \\
      \hyperref[sec:t2grid:empty]{\texttt{empty}} & -- & empties contents of grid\\
      \hyperref[sec:t2grid:flux_matrix]{\texttt{flux\_matrix}} & \texttt{scipy.sparse.lil\_matrix} & constructs a sparse matrix for calculating block-average flows \\
      \hyperref[sec:t2grid:fromgeo]{\texttt{fromgeo}} & \hyperref[t2grids]{\texttt{t2grid}} & constructs a TOUGH2 grid from a \texttt{mulgrid} object\\
      \hyperref[sec:t2grid:incons]{\texttt{incons}} & \hyperref[incons]{\texttt{t2incon}} & constructs initial conditions for the grid\\
      \hyperref[sec:t2grid:MINC]{\texttt{minc}} & list & creates MINC blocks and connections\\
      \hyperref[sec:t2grid:radial]{\texttt{radial}} & \hyperref[t2grids]{\texttt{t2grid}} & constructs a radial TOUGH2 grid\\
      \hyperref[sec:t2grid:rectgeo]{\texttt{rectgeo}} & (\hyperref[mulgrids]{\texttt{mulgrid}}, \texttt{dict}) & constructs a \texttt{mulgrid} object from a rectangular TOUGH2 grid\\
      \hyperref[sec:t2grid:rename_blocks]{\texttt{rename\_blocks}} & -- & renames blocks the grid\\
      \hyperref[sec:t2grid:rename_rocktype]{\texttt{rename\_rocktype}} & -- & renames a rock type in the grid\\
      \hyperref[sec:t2grid:reorder]{\texttt{reorder}} & -- & reorders blocks and connections in the grid\\
      \hyperref[sec:t2grid:rocktype_frequency]{\texttt{rocktype\_frequency}} & integer & frequency of use of a particular rock type\\
      \hyperref[sec:t2grid:sort_rocktypes]{\texttt{sort\_rocktypes}} & -- & sorts rock type list into alphabetical order by name\\
      \hyperref[sec:t2grid:write_vtk]{\texttt{write\_vtk}} & -- & writes grid to VTK file\\
      \hline
    \end{tabular}
    \caption{Methods of a \texttt{t2grid} object}
    \label{tb:t2grid_methods}
  \end{center}
\end{table}

\begin{snugshade}
\subsubsection{\texttt{+}}
\end{snugshade}
\label{sec:t2grid:plus}
\index{TOUGH2 grids!adding together}

Adds two grids \texttt{a} and \texttt{b} together (i.e. amalgamates them) to form a new grid \texttt{a+b}.  If any rock types, blocks or connections exist in both grids \texttt{a} and \texttt{b}, the value from \texttt{b} is used, so there are no duplicates.  (Technically this is really an `operator' rather than a method.)

\textbf{Parameters:}
\begin{itemize}
\item \textbf{a, b}: \hyperref[t2grids]{\texttt{t2grid}}\\
  The two grids to be added together.
\end{itemize}

\begin{snugshade}
\subsubsection{\texttt{add\_block(\emph{block})}}
\end{snugshade}
\label{sec:t2grid:add_block}
\index{TOUGH2 grids!adding!blocks}
\index{TOUGH2 grids!blocks!adding}

Adds a block to the grid.  If another block with the same name already exists, it is replaced.

\textbf{Parameters:}
\begin{itemize}
\item \textbf{block}: \hyperref[t2blockobjects]{\texttt{t2block}}\\
  Block to be added to the grid.
\end{itemize}

\begin{snugshade}
\subsubsection{\texttt{add\_connection(\emph{connection})}}
\end{snugshade}
\label{sec:t2grid:add_connection}
\index{TOUGH2 grids!adding!connections}
\index{TOUGH2 grids!connections!adding}

Adds a connection to the grid.  If another connection with the same column names already exists, it is replaced.

\textbf{Parameters:}
\begin{itemize}
\item \textbf{connection}: \hyperref[t2connectionobjects]{\texttt{t2connection}}\\
  Connection to be added to the grid.
\end{itemize}

\begin{snugshade}
\subsubsection{\texttt{add\_rocktype(\emph{rock})}}
\end{snugshade}
\label{sec:t2grid:add_rocktype}
\index{TOUGH2 grids!adding!rocktypes}
\index{TOUGH2 grids!rocktypes!adding}

Adds a rock type to the grid.  If another rock type with the same name already exists, it is replaced.

\textbf{Parameters:}
\begin{itemize}
\item \textbf{rock}: \hyperref[rocktypeobjects]{\texttt{rocktype}}\\
  Rock type to be added to the grid.
\end{itemize}

\begin{snugshade}
\subsubsection{\texttt{block\_index(\emph{blockname})}}
\end{snugshade}
\label{sec:t2grid:block_index}
\index{TOUGH2 grids!blocks!indices}
\index{TOUGH2 grids!indices!of blocks}

Returns the block index (in the \texttt{blocklist} list) of a specified block name.

\textbf{Parameters:}
\begin{itemize}
\item \textbf{blockname}: string\\
  Name of the block.
\end{itemize}

\begin{snugshade}
\subsubsection{\texttt{blockmap(\emph{geo}, \emph{index} = None)}}
\end{snugshade}
\label{sec:t2grid:blockmap}
\index{TOUGH2 grids!blocks!mappings}

Returns a mapping from the block name list of the specified geometry object to the block names in the grid.

\textbf{Parameters:}
\begin{itemize}
\item \textbf{geo}: \hyperref[mulgrids]{\texttt{mulgrid}}\\
  Geometry object.
\item \textbf{index}: list (or \texttt{None})\\
  Specifies a list of integer indices defining which blocks in the grid to map to. If \texttt{None}, all blocks are mapped to.
\end{itemize}

\begin{snugshade}
\subsubsection{\texttt{calculate\_block\_centres(\emph{geo})}}
\end{snugshade}
\label{sec:t2grid:calculate_block_centres}
\index{TOUGH2 grids!blocks!centres}
\index{TOUGH2 grids!centres!blocks}

Calculates geometrical centres of all blocks in the grid, based on the specified geometry object \texttt{geo}.

\textbf{Parameters:}
\begin{itemize}
\item \textbf{geo}: \hyperref[mulgrids]{\texttt{mulgrid}}\\
  Geometry object associated with the grid.
\end{itemize}

\begin{snugshade}
\subsubsection{\texttt{check(\emph{fix}=False,\emph{silent}=False)}}
\end{snugshade}
\label{sec:t2grid:check}
\index{TOUGH2 grids!checking}
\index{checking!TOUGH2 grids}

Checks a grid for errors and optionally fixes them.  Errors checked for are: blocks not connected to any other blocks, and blocks with isolated rocktypes (not shared with any neighbouring blocks).  Returns \texttt{True} if no errors were found, and \texttt{False} otherwise.  If \texttt{fix} is \texttt{True}, any identified problems will be fixed.  If \texttt{silent} is \texttt{True}, there is no printout (only really useful if \texttt{fix} is \texttt{True}).

Blocks not connected to any others are fixed by deleting them.  Isolated-rocktype blocks are fixed by assigning them the most popular rocktype of their neighbours.  Blocks with large volumes ($> 10^{20}$ m$^3$) are never considered isolated (because they often have a special rocktype, such as an atmosphere one, that their neighbours will never share).

\textbf{Parameters:}
\begin{itemize}
\item \textbf{fix}: Boolean\\
  Whether to fix any problems identified.
\item \textbf{silent}: Boolean\\
  Whether to print out feedback or not.
\end{itemize}

\begin{snugshade}
\subsubsection{\texttt{clean\_rocktypes}()}
\end{snugshade}
\label{sec:t2grid:clean_rocktypes}
\index{TOUGH2 grids!rocktypes!cleaning}

Deletes any rock types from the grid which are not assigned to any block.

\begin{snugshade}
\subsubsection{\texttt{connection\_index(\emph{blocknames})}}
\end{snugshade}
\label{sec:t2grid:connection_index}
\index{TOUGH2 grids!connections!indices}
\index{TOUGH2 grids!indices!of connections}

Returns the connection index (in the \texttt{connectionlist} list) of the connection between a specified pair of block names.

\textbf{Parameters:}
\begin{itemize}
\item \textbf{blocknames}: tuple\\
  A pair of block names, each of type string.
\end{itemize}

\begin{snugshade}
\subsubsection{\texttt{copy\_connection\_directions(\emph{geo},\emph{grid})}}
\end{snugshade}
\label{sec:t2grid:copy_connection_directions}
\index{TOUGH2 grids!connections!directions}

Copies the connection permeability directions for horizontal connections from another grid.  It is assumed that both grids have the same column structure, but may have different layer structures.

\textbf{Parameters:}
\begin{itemize}
\item \textbf{geo}: \hyperref[mulgrids]{\texttt{mulgrid}}\\
  Geometry object associated with the source grid.
\item \textbf{grid}: \hyperref[t2grids]{\texttt{t2grid}}\\
  The source grid from which the connection permeability directions are to be copied.
\end{itemize}

\begin{snugshade}
\subsubsection{\texttt{delete\_block(\emph{blockname})}}
\end{snugshade}
\label{sec:t2grid:delete_block}
\index{TOUGH2 grids!blocks!deleting}
\index{TOUGH2 grids!deleting!blocks}

Deletes a block from the grid.  This also deletes any connections involving the specified block.

\textbf{Parameters:}
\begin{itemize}
\item \textbf{blockname}: string\\
  Name of the block to be deleted from the grid.
\end{itemize}

\begin{snugshade}
\subsubsection{\texttt{delete\_connection(\emph{connectionname})}}
\end{snugshade}
\label{sec:t2grid:delete_connection}
\index{TOUGH2 grids!connections!deleting}
\index{TOUGH2 grids!deleting!connections}

Deletes a connection from the grid.

\textbf{Parameters:}
\begin{itemize}
\item \textbf{connectionname}: tuple (of string)\\
  Pair of block names identifying the connection to be deleted from the grid.
\end{itemize}

\begin{snugshade}
\subsubsection{\texttt{delete\_rocktype(\emph{rocktypename})}}
\end{snugshade}
\label{sec:t2grid:delete_rocktype}
\index{TOUGH2 grids!rocktypes!deleting}
\index{TOUGH2 grids!deleting!rocktypes}

Deletes a rock type from the grid.

\textbf{Parameters:}
\begin{itemize}
\item \textbf{rocktypename}: string\\
  Name of the rock type to be deleted from the grid.
\end{itemize}

\begin{snugshade}
\subsubsection{\texttt{demote\_block(\emph{blockname})}}
\end{snugshade}
\label{sec:t2grid:demote_block}
\index{TOUGH2 grids!blocks!demoting}

Shifts a block (or blocks) to the end of the blocklist.  This can be useful for making blocks inactive - by setting their volumes to zero or negative, and then shifting them to the end of the list (to avoid all blocks below them also being treated as inactive).

\textbf{Parameters:}
\begin{itemize}
\item \textbf{blockname}: string or list of strings\\
  Name(s) of the block(s) to be shifted to the end of the blocklist.
\end{itemize}

\begin{snugshade}
\subsubsection{\texttt{embed(\emph{subgrid}, \emph{connection})}}
\end{snugshade}
\label{sec:t2grid:embed}
\index{TOUGH2 grids!embedding}

Returns a grid with a subgrid embedded inside one of its blocks.  The connection specifies how the two grids are to be connected: the blocks to be connected and the connection distances, area etc. between them.

\textbf{Parameters:}
\begin{itemize}
\item \textbf{subgrid}: \hyperref[t2grids]{\texttt{t2grid}}\\
  Subgrid to be embedded.
\item \textbf{connection}: \hyperref[t2connectionobjects]{\texttt{t2connection}}\\
  Connection specifying how the subgrid is to be embedded, including the connection distances and area.  The first block should be the host block, the second the connecting block in the subgrid.
\end{itemize}

\begin{snugshade}
\subsubsection{\texttt{empty}()}
\end{snugshade}
\label{sec:t2grid:empty}
\index{TOUGH2 grids!emptying}

Empties the grid of all its blocks, rock types and connections.

\begin{snugshade}
\subsubsection{\texttt{flux\_matrix(\emph{geo}, \emph{blockmap} = \{\})}}
\end{snugshade}
\label{sec:t2grid:flux_matrix}
\index{TOUGH2 grids!flux matrices}

Takes the grid and a corresponding \hyperref[mulgrids]{\texttt{mulgrid}} object, and constructs a sparse matrix (of type \texttt{scipy.sparse.lil\_matrix}) which can be used to convert connection flow values on the grid to block-average fluxes (flows per unit area).  Specifically, if an array of connection flow values (one for each connection in the grid) is multiplied by this sparse matrix, the result is a partitioned array containing the 3-component block-average flux for each of the (non-atmosphere) blocks.

The method for constructing the matrix is as follows.  For each block, a distribution of flux is fitted to agree as closely as possible with the connection flow values.  This distribution is either constant or linear, depending on how many connections the block has (linear for blocks with at least 6 connections).  Fitting the connection values results in a small linear system to solve, which may be under- or over-determined, depending on the number of connections and the type of flux distribution.  A pseudo-inverse matrix is calculated which will find the least-squares solution of this system.  The total matrix is formed by assembling these matrices for each of the blocks into a global matrix.

\textbf{Parameters:}
\begin{itemize}
\item \textbf{geo}: \hyperref[mulgrids]{\texttt{mulgrid}}\\
  The \texttt{mulgrid} geometry object (see chapter \ref{mulgrids}).
\item \textbf{blockmap}: dictionary\\
  Dictionary mapping the block names in the geometry to the block naming system used in the grid.
\end{itemize}

\begin{snugshade}
\subsubsection{\texttt{fromgeo(\emph{geo})}}
\end{snugshade}
\label{sec:t2grid:fromgeo}
\index{TOUGH2 grids!creating!from MULgraph geometry}

Returns a grid constructed from a \texttt{mulgrid} geometry object.  (Any previous contents of the grid are first emptied.)

\textbf{Parameters:}
\begin{itemize}
\item \textbf{geo}: \hyperref[mulgrids]{\texttt{mulgrid}}\\
  The \texttt{mulgrid} geometry object (see chapter \ref{mulgrids}).
\end{itemize}

\begin{snugshade}
\subsubsection{\texttt{incons(\emph{values}=(101.3e3,20.))}}
\end{snugshade}
\label{sec:t2grid:incons}
\index{TOUGH2 grids!creating!initial conditions for}
\index{TOUGH2 grids!initial conditions}
\index{TOUGH2 initial conditions!creating}

Returns a \hyperref[incons]{\texttt{t2incon}} set of initial conditions for the grid, using the supplied values.  Initial conditions can be specified for only one block, in which case they will be applied to all blocks, or for each block, in an array.

\textbf{Parameters:}
\begin{itemize}
\item \textbf{values}: \texttt{tuple} or \texttt{np.array}\\
  Initial conditions values, either a \texttt{tuple} of values for one block, or an \texttt{np.array} with each row containing a set of values for one block. 
\end{itemize}

\begin{snugshade}
\subsubsection{\texttt{minc(\emph{volume\_fractions}, \emph{spacing}=50., \emph{num\_fracture\_planes}=1,\\
    \emph{blocks}=None, \emph{matrix\_blockname}=None, \emph{minc\_rockname}=None,\\
    \emph{proximity}=None, \emph{atmos\_volume}=1.e25, \emph{incon}=None,\\
    \emph{fracture\_connection\_distance}=0.)}}
\end{snugshade}
\label{sec:t2grid:MINC}
\index{TOUGH2 grids!creating!MINC}
\index{MINC!generating}

Creates ``Multiple Interacting Continua'' (MINC) blocks and connections in the grid, for simulating fracture flow with matrix blocks attached to each fracture block. This has capability similar to that of the GMINC program \citep{GMINC}, or of the MINC part of TOUGH2's \hyperref[sec:t2data:meshmaker]{MESHMAKER} section (except that matrix-matrix flow is not supported).

This function returns a rank-2 integer \texttt{np.array} with one row for each MINC level, containing the indices of the blocks for that level. For example, the first row is a list of all fracture block indices, the second is a list of all MINC level 1 block indices, etc. This can be useful for identifying all blocks in a given MINC level, for plotting or other post-processing.

For example, if the output index array from this method is \texttt{minc\_level}, and \texttt{T} is an array of temperatures computed over the entire MINC grid (e.g. extracted from the element table of a listing file), then the temperatures in MINC level \texttt{m} are given by:

\begin{lstlisting}
T[minc_level[m]]
\end{lstlisting}

Note that plotting MINC results over a \hyperref[mulgrids]{\texttt{mulgrid}} geometry can be made easier (particularly for grids that have MINC applied over only part of the domain) by using the \hyperref[sec:mulgrid:minc_array]{\texttt{minc\_array()}} method to create the solution vector to plot.

If the \texttt{incon} parameter is specified as a \hyperref[incons]{\texttt{t2incon}} object (from the original grid), then this method will also return a new \texttt{t2incon} object for the MINC grid, with values copied from the original.

Fracture blocks retain the same block name as their original porous medium blocks. The naming of matrix blocks can be controlled using the \texttt{matrix\_blockname} parameter.

\textbf{Parameters:}
\begin{itemize}
\item \textbf{volume\_fractions}: list (or \texttt{np.array})\\
  List or array of volume fractions. The first entry corresponds to the fractures, with subsequent entries specifying the volume fractions for each MINC level. The length of this list or array is therefore equal to one plus the number of matrix blocks to be used. Entries for all MINC levels must be present, but they need not sum to 1- if they do not, they will be scaled so that the sum is 1. (This means, for example, that entries may be specified as percentage values.)
\item \textbf{spacing}: float or list (or \texttt{np.array})\\
  Fracture spacing parameters. If a float value is specified, this is applied to all sets of fracture planes (see below). If a list or array is specified, each entry is applied to its corresponding set of fracture planes.
\item \textbf{num\_fracture\_planes}: integer\\
  Number of sets of fracture planes (1, 2 or 3).
\item \textbf{blocks}: list (or \texttt{None})\\
  List of blocks or block names, specifying which blocks are to have MINC applied. If this parameter is \texttt{None}, all blocks are processed (except inactive blocks).
\item \textbf{matrix\_blockname}: function (or \texttt{None})\\
  Function returning the name of a MINC matrix block (string), given the original block name (string) and MINC level (integer > 0). If \texttt{None}, a default function will be used, which simply replaces the first character of the original block name with the MINC level.
\item \textbf{minc\_rockname}: function (or \texttt{None})\\
  Function returning the MINC rocktype name, given the original rocktype name and MINC level ($\geq 0$). If \texttt{None}, a default function will be used, which leaves fracture blocks with their original rocktype (the properties of which can subsequently be edited), and for matrix blocks, simply replaces the first character of the original rocktype name with `X'.
\item \textbf{proximity}: function (or \texttt{None})\\
  Proximity function, returning the total matrix volume within a given distance (float) from the fracture faces. If \texttt{None}, a default function will be used, corresponding to the \texttt{num\_fracture\_planes} parameter.
\item \textbf{atmos\_volume}: float\\
  Maximum block volume for blocks to be considered part of the geometrical grid. Blocks with volume greater than this will be assumed to be boundary condition blocks and no MINC processing will be applied to them.
\item \textbf{incon}: \hyperref[incons]{\texttt{t2incon}} (or \texttt{None})\\
  Initial conditions object for the original grid, before MINC processing. If not \texttt{None}, then the method returns (as well as the block index array) a new \texttt{t2incon} object for the MINC grid, with values for each block copied from the original (for all MINC levels).
\item \textbf{fracture\_connection\_distance}: float\\
  Connection distance between fracture and matrix blocks. Default is zero, as in MESHMAKER, but in some situations a finite value (e.g. $10^{-10}$ m) can work better.
\end{itemize}


\begin{snugshade}
\subsubsection{\texttt{radial(\emph{rblocks}, \emph{zblocks}, \emph{convention}=0, \emph{atmos\_type}=2, \emph{origin}=[0,0],\\
    \emph{justify}='r', \emph{case}=None, \emph{dimension}=2, \emph{blockmap}=\{\}, \emph{chars}=ascii\_lowercase, \emph{spaces}=\texttt{True})}}
\end{snugshade}
\label{sec:t2grid:radial}
\index{TOUGH2 grids!creating!radial}

Returns a radial TOUGH2 grid with the specified radial and vertical block sizes.  Grid column and layer naming convention, atmosphere type and origin can be specified.  The optional \texttt{justify} and \texttt{case} parameters control the formatting of the character part of the block names.

The \texttt{dimension} parameter sets the flow dimension for `generalized radial flow', which can represent flow in fractured rocks and modifies the block volumes and areas (see \cite{barker_1988}).  The default \texttt{dimension} = 2 corresponds to standard radial flow.

\textbf{Parameters:}
\begin{itemize}
\item \textbf{rblocks}, \textbf{zblocks}: list (or \texttt{np.array})\\
  Lists (or arrays) of block sizes in the \emph{r} and \emph{z} directions.
\item \textbf{convention}: integer\\
  Naming convention for grid columns and layers - same as the \hyperref[geometry_format_conventions]{naming convention} for a \hyperref[mulgrids]{\texttt{mulgrid}} object.
\item \textbf{atmos\_type}: integer\\
  Type of atmosphere - also the same as the \hyperref[geometry_format_conventions]{atmosphere type} for a \hyperref[mulgrids]{\texttt{mulgrid}} object.
\item \textbf{origin}: list (or \texttt{np.array})\\
  Origin of the grid (of length 2 or 3).  The first entry is the radial origin, i.e. the starting radius of the grid.  The last entry is the vertical origin, i.e. the vertical position of the top of the grid.  If of length 3, the middle entry is ignored.
\item \textbf{justify}: string\\
  Specify `r' for the character part of the block names (first three characters) to be right-justified, `l' for left-justified.
\item \textbf{case}: string\\
  Specify `l' for the character part of the block names (first three characters) to be lower case, `u' for upper case. Alternatively, use the more flexible \texttt{chars} parameter (see below).
\item \textbf{dimension}: float\\
  Dimension for `generalized radial flow', which can take any (possibly non-integer) value between 1 and 3.  Dimension 1 corresponds to flow in a linear `pipe', dimension 2 corresponds to standard radial flow in a disc-shaped reservoir and dimension 3 corresponds to flow in a spherically symmetric reservoir.
\item \textbf{blockmap}: dictionary\\
  Dictionary mapping the block names in the geometry to the block naming system used in the grid.
\item \textbf{chars}: string\\
  Specify a string of characters to be used to form the character part of block names.  For example, to use both lowercase and uppercase characters, set \texttt{chars} to \texttt{ascii\_lowercase + ascii\_uppercase}, or to use uppercase letters only, specify \texttt{ascii\_uppercase}.
\item \textbf{spaces}: Boolean\\
  Specify \texttt{False} to disallow spaces in character part of block names. In this case, the first element of the \texttt{chars} parameter functions like a `zero' and replaces spaces.
\end{itemize}

Visualization of radial $r-z$ model grids and results can be done in PyTOUGH by creating a `dummy' vertical slice rectangular geometry, using the \texttt{mulgrid} \hyperref[sec:mulgrid:rectangular]{\texttt{rectangular()}} method, using its $x$ direction for radius (and having only one block in the $y$ direction - which is not used).  The \hyperref[sec:mulgrid:slice_plot]{\texttt{slice\_plot()}} method can then be used to plot results.

\begin{snugshade}
\subsubsection{\texttt{rectgeo(\emph{origin\_block}=None, \emph{atmos\_volume}=1.e25, \emph{remove\_inactive}=False,\\
    \emph{convention}=0, \emph{atmos\_type}=2, \emph{justify}='r', \emph{chars}=ascii\_lowercase,\\
    \emph{spaces}=\texttt{True}, \emph{layer\_snap}=0.1, \emph{block\_order}=None)}}
\end{snugshade}
\label{sec:t2grid:rectgeo}
\index{MULgraph geometry!creating!from rectangular TOUGH2 grid}
\index{TOUGH2 grids!rectangular}

Creates a \hyperref[mulgrids]{\texttt{mulgrid}} geometry object from a rectangular TOUGH2 grid. It also returns a dictionary defining the mapping from the geometry block names to the grid block names. This block mapping can be used when the block naming convention used by the original TOUGH2 grid is not compatible with the layer/column based \hyperref[geometry_format_conventions]{naming conventions} assumed by a \texttt{mulgrid} geometry.

The method works within the following assumptions:
\begin{itemize}
  \item the grid is in fact rectangular (results will not be predictable otherwise)
  \item block centre coordinates are present for all blocks in the grid
  \item the bottom layer of blocks is complete (no missing blocks)
\end{itemize}

The method should work on rectangular TOUGH2 grids that have been translated and/or horizontally rotated with respect to the coordinate axes. Grids with incomplete upper layers (e.g. representing topography) should also be OK.

\textbf{Parameters:}
\begin{itemize}
\item \textbf{origin\_block}: string, \hyperref[t2blockobjects]{\texttt{t2block}} or \texttt{None}\\
  The block on the bottom layer of the geometry, at the origin of the axes defined by permeability directions 1 and 2. If \texttt{None}, it will be detected. Specify it manually if the algorithm does not detect it correctly.
  \item \textbf{atmos\_volume}: float\\
    Maximum block volume for blocks to be considered part of the geometrical grid. Blocks with volume greater than this will be assumed to be boundary condition blocks and will not be represented geometrically.
  \item \textbf{remove\_inactive}: Boolean\\
    Set \texttt{True} to remove inactive blocks from the geometry. TOUGH2 treats all blocks with zero or negative volume, and all subsequent blocks in the block list, to be inactive. If this option is used, the inactive blocks will be used to detect the surface elevations of the columns in the geometry. Otherwise, inactive blocks will be retained in the geometry.
\item \textbf{convention}: integer\\
  \hyperref[geometry_format_conventions]{Naming convention} for grid columns and layers in the output geometry.
\item \textbf{atmos\_type}: integer\\
  \hyperref[geometry_format_conventions]{Type} of atmosphere for the output geometry.
\item \textbf{justify}: string\\
  Specify `r' for the character part of the block names (first three characters) to be right-justified, `l' for left-justified.
\item \textbf{chars}: string\\
  Specify a string of characters to be used to form the character part of block names.  For example, to use both lowercase and uppercase characters, set \texttt{chars} to \texttt{ascii\_lowercase + ascii\_uppercase}, or to use uppercase letters only, specify \texttt{ascii\_uppercase}.
\item \textbf{spaces}: Boolean\\
  Specify \texttt{False} to disallow spaces in character part of block names. In this case, the first element of the \texttt{chars} parameter functions like a `zero' and replaces spaces.
\item \textbf{layer\_snap}: float\\
  Smallest desired surface block thickness.  Set to a positive value to eliminate surface blocks in the geometry with very small thicknesses (resulting from column surface elevations that are very close to the bottom of a layer).  Default value is 0.1 m. Note that it is not recommended to use a value of zero, as spurious small-thickness surface blocks can arise from rounding errors in reading the data file. If this still occurs, try increasing the snap value until they disappear.
\item \textbf{block\_order}: string or \texttt{None}\\
  Specify \texttt{None} or `layer\_column' for default block ordering by layer and column, starting from the atmosphere. Specify `dmplex' to order blocks by geometrical type (8-node hexahedrons first followed by 6-node wedges) as in PETSc DMPlex meshes.
\end{itemize}

\begin{snugshade}
\subsubsection{\texttt{rename\_blocks(\emph{blockmap} = \{\}, \emph{fix\_blocknames} = True)}}
\end{snugshade}
\label{sec:t2grid:rename_blocks}
\index{TOUGH2 grids!blocks!renaming}

Renames blocks in the grid according to the specified block mapping dictionary. Any block whose name is a key of the block mapping dictionary is renamed with the corresponding dictionary value. Related properties such as connections are also renamed.

\textbf{Parameters:}
\begin{itemize}
\item \textbf{blockmap}: dictionary\\
  Block mapping dictionary, mapping strings to strings.
\item \textbf{fix\_blocknames}: Boolean\\
  Set \texttt{True} (the default) to `fix' block names in the dictionary, using the \hyperref[sec:mulgrid:fix_blockname]{\texttt{fix\_blockname()}} function. 
\end{itemize}

\begin{snugshade}
\subsubsection{\texttt{rename\_rocktype(\emph{rockname}, \emph{newrockname})}}
\end{snugshade}
\label{sec:t2grid:rename_rocktype}
\index{TOUGH2 grids!rocktypes!renaming}

Renames a rock type in the grid. An exception is raised if the specified rocktype name does not exist, or if the new target rocktype name has already been used.

\textbf{Parameters:}
\begin{itemize}
\item \textbf{rockname}: string\\
  Name of the rock type to be renamed.
\item \textbf{newrockname}: string\\
  New name for the rock type.
\end{itemize}

\begin{snugshade}
\subsubsection{\texttt{reorder(\emph{block\_names}, \emph{connection\_names}=\texttt{None}, \emph{geo}=\texttt{None})}}
\end{snugshade}
\label{sec:t2grid:reorder}
\index{TOUGH2 grids!reordering}

Reorders the blocks (and optionally connections) in the grid.

\textbf{Parameters:}
\begin{itemize}
\item \textbf{block\_names}: list of string (or \texttt{None})\\
  List specifying the names of the blocks, in their desired
  order. Each block name must exist in the grid, otherwise an error
  will be raised. If this parameter is \texttt{None} (the default),
  blocks are not reordered (unless a geometry is specified
  instead).
\item \textbf{connection\_names}: list of string (or \texttt{None})\\
  List specifying the names of the connections, in their desired
  order. Each item in the list should be a tuple of block names. The
  ordering of the block names in any tuple may be reversed with
  respect to the original connection naming. However an error will be
  raised if any tuple of block names in the list does not exist in the
  grid (in either its forward or reverse form). If this parameter is
  \texttt{None} (the default), connections are not reordered (unless a
  geometry is specified instead).
\item \textbf{geo}: \hyperref[mulgrids]{\texttt{mulgrid}} geometry (or \texttt{None})\\
  Geometry object to use for the reordering. If this is specified, the
  geometry's block and connection name lists are used (and the
  previous parameters are ignored). After reordering, the grid's
  blocks and connections will have the same ordering as if the grid
  had been created using the \hyperref[sec:t2grid:fromgeo]{\texttt{fromgeo()}} method.
\end{itemize}

\begin{snugshade}
\subsubsection{\texttt{rocktype\_frequency(\emph{rockname})}}
\end{snugshade}
\label{sec:t2grid:rocktype_frequency}
\index{TOUGH2 grids!rocktypes!frequencies}

Returns the frequency of use of the rock type with the specified name, i.e. how many blocks are assigned that rock type.

\textbf{Parameters:}
\begin{itemize}
\item \textbf{rockname}: string\\
  Name of the specified rock type.
\end{itemize}

\begin{snugshade}
\subsubsection{\texttt{sort\_rocktypes()}}
\end{snugshade}
\label{sec:t2grid:sort_rocktypes}
\index{TOUGH2 grids!rocktypes!sorting}

Sorts the rocktype list into alphabetical order by name.

\begin{snugshade}
\subsubsection{\texttt{write\_vtk(\emph{geo}, \emph{filename}, \emph{wells}=False, \emph{blockmap} = \{\}, \emph{surface\_snap}=0.1)}}
\end{snugshade}
\label{sec:t2grid:write_vtk}
\index{TOUGH2 grids!writing!VTK files}
\index{Visualization Tool Kit (VTK)}

Writes a \texttt{t2grid} object to a VTK file on disk, for visualisation with VTK, Paraview, Mayavi etc.  The grid is written as an `unstructured grid' VTK object with data arrays defined on cells.  The data arrays written, in addition to the defaults arrays for the associated \texttt{mulgrid} object, are: rock type index, porosity and permeability for each block.  A separate VTK file for the wells in the grid can optionally be written.

\textbf{Parameters:}
\begin{itemize}
\item \textbf{geo}: \hyperref[mulgrids]{\texttt{mulgrid}}\\
  The \texttt{mulgrid} geometry object associated with the grid.  This is required as the \texttt{t2grid} object does not contain any spatial information, e.g. locations of block vertices.
\item \textbf{filename}: string\\
  Name of the VTK file to be written.  This is also required.
\item \textbf{wells}: Boolean\\
  Set to \texttt{True} if the wells from the \texttt{mulgrid} object are to be written to a separate VTK file.
\item \textbf{blockmap}: dictionary\\
  Dictionary mapping the block names in the geometry to the block naming system used in the grid.
\item \textbf{surface\_snap}: float\\
  Tolerance for specifying how close column surface elevations need to be before being considered ``equal'' when constructing surface nodes.
\end{itemize}

\section{Other objects (\texttt{rocktype}, \texttt{t2block} and \texttt{t2connection})}

A \texttt{t2grid} object contains lists of other types of objects: \texttt{rocktype}, \texttt{t2block} and \texttt{t2connection}.  These classes are described below.

\subsection{\texttt{rocktype} objects}
\label{rocktypeobjects}
\index{PyTOUGH!classes!\texttt{rocktype}}
\index{TOUGH2 grids!rocktypes}

A \texttt{rocktype} object represents a TOUGH2 rock type.  The properties of a \texttt{rocktype} object, and their default values, are given in Table \ref{tb:rocktype_properties}.

The main familiar properties of a rock type are referred to in a natural way, e.g. the porosity of a rock type \texttt{r} is given by \texttt{r.porosity}.  The permeability property is a 3-element \texttt{np.array}, giving the permeability in each of the three principal axes of the grid, so e.g. the vertical permeability of a rock type \texttt{r} would normally be given by \texttt{r.permeability[2]} (recall that array indices in Python are zero-based, so that the third element has index 2).

Some rock type properties are optional, and only need be specified when the property \texttt{nad} is greater than zero.  An example is the relative permeability and capillarity functions that can be specified for a rock type when \texttt{nad} $\ge$ 2.  The way these functions are specified is described in chapter \ref{datafiles}.

\textbf{Example:}

\begin{lstlisting}
r = rocktype(name = 'ignim', permeability = [10.e-15, 10.e-15, 2.e-15], specific_heat = 850)
\end{lstlisting}

declares a rocktype object called \texttt{r} with name `ignim', permeability of 10 mD in the first and second directions and 2 mD in the vertical direction, and specific heat 850 J.kg$^{-1}$.K$^{-1}$.

(Note that when declaring rock types, the permeability can for convenience be specified as a list, which will be converted internally to an \texttt{np.array}.)

\index{TOUGH2 grids!rocktypes!properties}
\begin{table}
  \begin{center}
    \begin{tabular}{|l|l|p{30mm}|l|}
      \hline
      \textbf{Property} & \textbf{Type} & \textbf{Description} & \textbf{Default}\\
      \hline
      \texttt{capillarity} & dictionary & capillarity function & --\\
      \texttt{compressibility} & float & compressibility & 0 m$^2$.N$^{-1}$\\
      \texttt{conductivity} & float & heat conductivity & 1.5 W.m$^{-1}$.K$^{-1}$\\
      \texttt{density} & float & rock grain density & 2600 kg.m$^{-3}$\\
      \texttt{dry\_conductivity} & float & dry heat conductivity & wet heat conductivity\\
      \texttt{expansivity} & float & expansivity & 0 K$^{-1}$\\
      \texttt{klinkenberg} & float & Klinkenberg parameter & 0 Pa$^{-1}$\\
      \texttt{nad} & integer & number of extra data lines & 0\\
      \texttt{name} & string & rock type name & `dfalt'\\
      \texttt{permeability} & \texttt{np.array} & permeability & \texttt{np.array}([10$^{-15}$]*3) m$^2$\\
      \texttt{porosity} & float & porosity & 0.1\\
      \texttt{relative\_permeability} & dictionary & relative permeability function & --\\
      \texttt{specific\_heat} & float & rock grain specific heat & 900 J.kg$^{-1}$.K$^{-1}$\\
      \texttt{tortuosity} & float & tortuosity factor & 0\\
      \texttt{xkd3} & float & used by EOS7R & 0 m$^{3}$.kg$^{-1}$\\
      \texttt{xkd4} & float & used by EOS7R & 0 m$^{3}$.kg$^{-1}$\\
      \hline
    \end{tabular}
    \caption{Properties of a \texttt{rocktype} object}
    \label{tb:rocktype_properties}
  \end{center}
\end{table}

\subsection{\texttt{t2block} objects}
\label{t2blockobjects}
\index{PyTOUGH!classes!\texttt{t2block}}
\index{TOUGH2 grids!blocks}

A \texttt{t2block} object represents a block in a TOUGH2 grid.  The properties of a \texttt{t2block} object are given in Table \ref{tb:t2block_properties}.  These reflect the specifications of a TOUGH2 block as given in a TOUGH2 data file, with the exception of the \texttt{atmosphere}, \texttt{centre}, \texttt{connection\_name}, \texttt{neighbour\_name} and \texttt{num\_connections} properties.

The \texttt{atmosphere} property determines whether the block is to be treated as an atmosphere block.  The \texttt{centre} property can optionally be used to specify the coordinates of the centre of a block.  Block centres are automatically calculated when a \hyperref[t2grids]{\texttt{t2grid}} object is constructed from a \hyperref[mulgrids]{\texttt{mulgrid}} object using the \hyperref[sec:t2grid:fromgeo]{\texttt{fromgeo}} method).  The \texttt{connection\_name} property is a set containing the names (as tuples of strings) of all connections involving the block.

A \texttt{t2block} object has no methods.

\index{TOUGH2 grids!blocks!properties}
\begin{table}
  \begin{center}
    \begin{tabular}{|l|l|l|l|}
      \hline
      \textbf{Property} & \textbf{Type} & \textbf{Description}\\
      \hline
      \texttt{ahtx} & float & interface area for heat exchange (TOUGH2 only)\\
      \texttt{atmosphere} & Boolean & whether block is an atmosphere block or not\\
      \texttt{centre} & \texttt{np.array} & block centre (optional)\\
      \texttt{connection\_name} & set & names of connections involving the block\\
      \texttt{nadd} & integer & increment between block numbers in sequence\\
      \texttt{name} & string & block name\\
      \texttt{neighbour\_name} & set & names of neighbouring (connected) blocks\\
      \texttt{nseq} & integer & number of additional blocks in sequence\\
      \texttt{num\_connections} & integer & number of connections containing the block\\
      \texttt{pmx} & float & permeability modifier (TOUGH2 only)\\
      \texttt{rocktype} & \texttt{rocktype} & rock type\\
      \texttt{volume} & float & block volume\\
      \hline
    \end{tabular}
    \caption{Properties of a \texttt{t2block} object}
    \label{tb:t2block_properties}
  \end{center}
\end{table}

\subsection{\texttt{t2connection} objects}
\label{t2connectionobjects}
\index{PyTOUGH!classes!\texttt{t2connection}}
\index{TOUGH2 grids!connections}

A \texttt{t2connection} object represents a connections between two TOUGH2 blocks.  The properties of a \texttt{t2connnection} object are given in Table \ref{tb:t2connection_properties}.  These correspond to the properties of a connection specified in a TOUGH2 data file.  Note that the \texttt{block} property returns \hyperref[t2blockobjects]{\texttt{t2block}} objects, not just the names of the blocks in the connection.  Hence, for example, the volume of the first block in a connection object \texttt{con} is given simply by \texttt{con.block[0].volume}.

A \texttt{t2connection} object has no methods.

\index{TOUGH2 grids!connections!properties}
\begin{table}
  \begin{center}
    \begin{tabular}{|l|l|l|l|}
      \hline
      \textbf{Property} & \textbf{Type} & \textbf{Description}\\
      \hline
      \texttt{area} & float & connection area\\
      \texttt{block} & \texttt{list} & two-element list of blocks\\
      \texttt{dircos} & float & gravity direction cosine\\
      \texttt{direction} & integer & permeability direction (1, 2, or 3)\\
      \texttt{distance} & \texttt{list} & two-element list of connection distances\\
      \texttt{nad1,nad2} & integer & increments in sequence numbering\\
      \texttt{nseq} & integer & number of additional connections in sequence\\
      \texttt{sigma} & float & radiant emittance factor (TOUGH2 only)\\
      \hline
    \end{tabular}
    \caption{Properties of a \texttt{t2connection} object}
    \label{tb:t2connection_properties}
  \end{center}
\end{table}

\section{Example}
\index{examples!TOUGH2 grids}

The following piece of Python script creates a rectangular 2-D slice TOUGH2 grid with two rock types, and assigns these rock types to blocks in the grid according to their position along the slice.

\begin{lstlisting}
from t2grids import *

geo = mulgrid().rectangular([500]*20, [1000], [100]*20, atmos_type = 0, convention = 2)
geo.write('2Dgrd.dat')
grid = t2grid().fromgeo(geo)

grid.add_rocktype(rocktype('greyw', permeability = [1.e-15]*2 + [0.1e-15]))
grid.add_rocktype(rocktype('fill ', permeability = [15.e-15]*2 + [5.e-15]))

for blk in grid.blocklist[1:]:
    if 200 <= blk.centre[0] <= 400: blk.rocktype = grid.rocktype['fill ']
    else: blk.rocktype = grid.rocktype['greyw']
\end{lstlisting}

The first line just imports the required PyTOUGH library.  (It is not necessary to import the \texttt{mulgrids} library explicitly, because it is used and therefore imported by the \texttt{t2grids} library.)

The second block of code creates a rectangular MULgraph geometry object with 20 columns (each 500 m wide) along the slice and 20 layers (each 100 m thick), writes this to a geometry file on disk, and creates a TOUGH2 grid from it.

Then the two rock types are created, \texttt{'greyw'} and \texttt{'fill '}.  (Note that rock types are expected by TOUGH2 to have names 5 characters long, so it is necessary to add spaces to shorter names.)

The final part assigns the rock types to the blocks in the grid.  The loop starts from 1 instead of 0, so that the atmosphere block is skipped.  In this example, the blocks in the grid are assigned the \texttt{'fill '} rock type if they are between 200 m and 400 m along the slice.  Blocks outside this region are assigned the \texttt{'greyw'} rock type.
